package cn.xing.modules.sys.service.impl;

import cn.xing.common.exception.RRException;
import cn.xing.common.utils.PageUtils;
import cn.xing.common.utils.Query;
import cn.xing.enums.AftersaleStatusEnum;
import cn.xing.enums.OrderStatusEnum;
import cn.xing.modules.app.dto.AfterSaleDto;
import cn.xing.modules.app.entity.UserEntity;
import cn.xing.modules.app.service.AlipayService;
import cn.xing.modules.app.service.OrderService;
import cn.xing.modules.app.service.SysNotificationService;
import cn.xing.modules.app.service.UserReminderService;
import cn.xing.modules.sys.dao.AfterSaleDao;
import cn.xing.modules.sys.entity.AfterSaleEntity;
import cn.xing.modules.sys.service.AfterSaleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;


@Slf4j
@Service("afterSaleService")
public class AfterSaleServiceImpl extends ServiceImpl<AfterSaleDao, AfterSaleEntity> implements AfterSaleService {
    @Autowired
    private AlipayService alipayService;
    @Autowired
    private OrderService orderService;

    @Autowired
    private UserReminderService userReminderService;

    @Autowired
    private SysNotificationService sysNotificationService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createAfterSale(AfterSaleDto afterSaleDto, UserEntity user) {
        String orderSn = afterSaleDto.getOrderSn();
        // 查看是否存在 orderSn对应 的记录
        checkUnique(orderSn);

        // 合法检查
        orderService.checkSatisfyAfterSale(orderSn, user.getUserId());

        // 保存
        AfterSaleEntity afterSaleEntity = new AfterSaleEntity();
        afterSaleEntity.setOrderSn(orderSn);
        afterSaleEntity.setReason(afterSaleDto.getReason());
        afterSaleEntity.setImgUrls(afterSaleDto.getImgUrls());
        afterSaleEntity.setStatus(0);

        this.baseMapper.insert(afterSaleEntity);

        // 通知商家 有新的售后申请
        sysNotificationService.onUserRequireAfterSale(orderSn);
    }

    /**
     * 检查 该订单是否已存在售后记录
     *
     * @param orderSn
     */
    private void checkUnique(String orderSn) {
        if (null != queryByOrderSn(orderSn)) {
            throw new RRException("已存在售后记录，请勿再次申请");
        }
    }

    @Override
    public AfterSaleEntity queryByOrderSn(String orderSn) {
        return this.baseMapper.selectOne(
                new QueryWrapper<AfterSaleEntity>()
                        .eq("order_sn", orderSn)
        );
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String key = (String) params.get("key");

        IPage<AfterSaleEntity> page = this.page(
                new Query<AfterSaleEntity>().getPage(params),
                new QueryWrapper<AfterSaleEntity>()
                        .orderByDesc("update_time")
                        .eq(StringUtils.isNotEmpty(key), "order_sn", key)
                        .or()
                        .like(StringUtils.isNotEmpty(key), "reason", key)

        );

        return new PageUtils(page);
    }

    @Override
    public void refuse(Long id) {
        AfterSaleEntity afterSaleEntity = getById(id);
        // 用户提交
        if (!AftersaleStatusEnum.NEW.getCode().equals(afterSaleEntity.getStatus())) {
            throw new RRException("售后状态不正确");
        }

        doUpdateAfterSaleStatus(afterSaleEntity, AftersaleStatusEnum.BUSINESS_REFUSE);
    }

    @Override
    public void confirm(Long id) {
        AfterSaleEntity afterSaleEntity = getById(id);
        // 用户提交
        if (!AftersaleStatusEnum.NEW.getCode().equals(afterSaleEntity.getStatus())) {
            throw new RRException("售后状态不正确");
        }

        // 更新售后状态
        doUpdateAfterSaleStatus(afterSaleEntity, AftersaleStatusEnum.BUSINESS_CONFIRM);

        refundAndMarkAfterSale(afterSaleEntity);
    }

    @Transactional(rollbackFor = Exception.class)
    public void refundAndMarkAfterSale(AfterSaleEntity afterSaleEntity) {
        boolean refundSuccess = true;
        // 支付宝退款
        String orderSn = afterSaleEntity.getOrderSn();
        try {
            alipayService.refund(orderSn, "商家同意售后");
        } catch (Exception e) {
            refundSuccess = false;

            log.warn("支付宝退款出错:[{}]", e.getMessage());
            e.printStackTrace();
        }

        // 退款成功则 更新
        if (refundSuccess) {
            doUpdateAfterSaleStatus(afterSaleEntity, AftersaleStatusEnum.REFUNDED);
            orderService.doUpdateOrderStatus(orderSn, OrderStatusEnum.REFUNDED.getCode());
        }

    }

    private void doUpdateAfterSaleStatus(AfterSaleEntity afterSaleEntity, AftersaleStatusEnum statusEnum) {
        afterSaleEntity.setStatus(statusEnum.getCode());

        updateById(afterSaleEntity);
        //todo 售后消息通知
        switch (statusEnum) {
            case BUSINESS_REFUSE:
                userReminderService.onAfterSaleRefuse(afterSaleEntity);
                break;
            case NEW:
                break;
            case BUSINESS_CONFIRM:
                userReminderService.onAfterSaleConfirm(afterSaleEntity);
                break;
            case REFUNDED:
                break;
            default:
                log.warn("售后状态错误，订单号[{}]", afterSaleEntity.getOrderSn());
        }
    }
}